'''
# 结构型模式之组合模式
**定义**：将对象组合成树形结构以表示“部分-整体”的层次结构，组合模式使得用户对单个对象和组合对象的使用具有一致性
**实例**：运用组合模式实现文件目录结构的创建与管理。
          一个树形目录结构，目录下可以有子目录和具体文件（叶节点），子目录和目录的行为方法相同，对外界有相同的接口。
          对一个目录来说，该目录下的子目录和具体文件也具有一致性。
**说明**：File类表示文件，文件是一个树形结构中的叶节点，没有find,add,remove方法;
          Directory类表示目录，从File类继承，同时实现了find,add,remove方法，用于寻找、添加、删除文件（或子目录）
'''
###################################################
class File(object):
    def __init__(self, name):
        super(File, self).__init__()
        self.name = name
        self.chidren = []

    # 列出树形目录结构
    def list(self, depth = 0):
        print('-'*depth + self.name)
        for cld in self.chidren:
            cld.list(depth + 2)


class Directory(File):
    def find(self, name):
        for cld in self.chidren:
            if cld.name == name:
                return cld
        else:
            raise Exception("name not found!")

    def add(self, chidren):
        try:
            self.find(chidren.name)
        except Exception as e:
            self.chidren.append(chidren)
        else:
            raise Exception("name already exists!")
        
    def remove(self, name):
        cld = self.find(name)
        self.chidren.remove(cld)

###################################################
'''
# 客户端测试代码
**说明**：
首先生成一颗目录树
root
|-file1
|-file2
|-dir1
  |-file3
  |-file4
  |-dir2
    |-file5
    |-file6
然后将目录结构中的文件file1和目录dir2删除
root
|-file2
|-dir1
  |-file3
  |-file4
'''
def main():
    print("生成目录树...")
    # 添加文件和添加子目录的接口一致
    root = Directory('root')
    root.add(File('file1'))
    root.add(File('file2'))
    dir1 = Directory('dir1')
    dir1.add(File('file3'))
    dir1.add(File('file4'))
    root.add(dir1)
    dir2 = Directory('dir2')
    dir2.add(File('file5'))
    dir1.add(dir2)
    dir2.add(File('file6'))
    print("生成目录树完成")

    root.list()

    print("移除文件...")
    # 删除文件和删除目录的接口一致
    # 目录和子目录的接口一致
    root.remove('file1')
    dir1.remove('dir2')
    print("移除文件完成")

    root.list()

if __name__ == '__main__':
    main()